//
//  Alertable.swift
//  FrameProduct
//
//  Created by delegate on 2024/2/3.
//
//  声明弹框相关的协议
import UIKit

/// 根据类型T创建对应弹框
/// - Parameters:
///   - alertType: 弹框的类型，根据此类型初始化对应弹框
///   - title: 弹框的标题
///   - message: 弹框的内容
///   - style: 弹框的样式
/// - Returns:
///   - 返回一个Alert 实例本身
///
///  - Examples:
///     createAlert(alertType: Toast.self, message: "请阅读用户服务协议和隐私政策并勾选", style: .info)
///         .offset(CGPoint(x: 0, y: -50))
///         .bind(action: Toast.Action(title: "确定"))
///         .show()
public func createAlert<T: Alertable>(alertType: T.Type, title: String? = nil, message: String?, style: T.Style) -> T {
    alertType.with(title: title, message: message, style: style)
}

/// 规范一个可提醒的对话框的协议
public protocol Alertable: AlertActionBindable & AlertPresentable {
    
    associatedtype Style
    associatedtype Action
    
    /// 初始化一个alert 实例
    ///
    /// - Parameters:
    ///   - title: 弹框的标题
    ///   - message: 弹框的内容
    ///   - style: 弹框的样式
    /// - Returns:
    ///   - 返回一个Alert 实例本身
    static func with(title: String?, message: String?, style: Style) -> Self
}

/// 规范一个对话框弹出的协议
public protocol AlertPresentable {
    
    /// 在一个控制器上弹出弹框，当传入的控制器为nil时，弹到当前顶部显示的控制器
    ///
    /// - Parameters:
    ///   - convertible: 弹框要弹到的目标控制器
    ///   - completion: 弹框 显示完成的回调
    func show(on convertible: ViewConvertible?, completion: (() -> Void)?) -> Self
    
    /// 移除弹框
    func dismiss(animated: Bool)
}

/// 规范一个对话框添加一个按钮的协议
public protocol AlertActionBindable {
    associatedtype Action
    /// 给弹框 添加一个按钮
    ///
    /// - Parameters:
    ///   - action: 设置的按钮 UIAlertAction
    /// - Returns:
    ///   - 返回一个Alert 实例本身
    func bind(action: Action) -> Self
}

/// 规范一个对话框添加一个输入框的协议
public protocol AlertTextFieldBindable {
    
    /// 给弹框 添加一个文本输入框
    ///
    /// - Parameters:
    ///   - text: 文本输入框默认展示的文本，可以为nil
    ///   - placeholder: 文本输入框的占位文本，不能为空
    ///   - isSecure: 是否为安全的输入框，密码可使用
    ///   - configurationHandler: 用来配置文本输入框的属性
    /// - Returns:
    ///   - 返回一个Alert 实例本身
    func bind(textField text: String?, placeholder: String, isSecure: Bool, configurationHandler: ((UITextField) -> Void)?) -> Alert
}
